package com.zmn.plat.services.impl.channel;

import com.zmn.common.dictionary.GlobalDict;
import com.zmn.common.dto.VtDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.manager.common.database.annotation.ReadOnlyConnection;
import com.zmn.mcc.permit.mysql.annotation.ZmnDPermit;
import com.zmn.mcc.permit.mysql.enums.DPermitTypeEnum;
import com.zmn.plat.common.constant.RedisKeyConstant;
import com.zmn.plat.manager.dictionary.ChannelDict;
import com.zmn.plat.model.entity.channel.*;
import com.zmn.plat.model.vo.channel.ChannelCountVo;
import com.zmn.plat.persistence.interfaces.channel.ChannelDAO;
import com.zmn.plat.services.interfaces.channel.ChannelService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 渠道new
 *
 * @author xiangjunming
 * @since 2019/08/19 11:57:57
 */
@Slf4j
@Service
public class ChannelServiceImpl implements ChannelService {

    @Resource
    private ChannelDAO channelDAO;

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public Channel findByKey(Integer channelId) {

        return channelDAO.findByKey(channelId);
    }

    /**
     * 根据渠道ID查询渠道名称
     *
     * @param channelId 渠道id
     * @return 渠道名称
     * @author xujie
     * @since 2021-03-02 18:10
     */
    @Override
    public String findNameByKey(Integer channelId) {

        if (channelId == null) {
            return null;
        }
        return channelDAO.findNameByKey(channelId);
    }

    /**
     * 根据渠道ID列表查询渠道名称
     *
     * @param channelIdList 渠道id列表
     * @return 渠道名称
     * @author xujie
     * @since 2021-04-13
     */
    @Override
    @ReadOnlyConnection
    public List<ChannelIdAndName> listNameByChannelIds(List<Integer> channelIdList) {

        if (channelIdList == null || channelIdList.size() == 0) {
            return new ArrayList<>();
        } else {
            return channelDAO.listNameByChannelIds(channelIdList);
        }
    }

    /**
     * 根据搜索值模糊查询渠道id
     *
     * @param searchValue 搜索值
     * @return 渠道id 列表
     * @author xujie
     * @since 2021-04-13
     */
    @Override
    @ReadOnlyConnection
    public List<Integer> findChannelIdBySearchValue(String searchValue) {

        if (StringUtil.isBlank(searchValue)) {
            return new ArrayList<>();
        }
        return channelDAO.findChannelIdBySearchValue(searchValue);
    }

    @Override
    public List<Channel> listByChannelIds(List<Integer> channelIds) {
        if (CollectionUtil.isNullOrEmpty(channelIds)) {
            return new ArrayList<>();
        }
        return channelDAO.listByChannelIds(channelIds);
    }

    @Override
    public List<Channel> listOneLevelChannel() {
        return channelDAO.listByOneLevel();
    }

    @Override
    public List<Channel> listTwoLevelChannel(Integer plat, Integer channelType) {
        return channelDAO.listTwoLevelChannel(plat, channelType);
    }

    @Override
    public List<Channel> listChannelByNotCps(Integer plat, Integer channelType) {
        return channelDAO.listChannelByNotCps(plat, channelType);
    }

    @Override
    public List<Channel> listByParentId(Integer parentId) {
        return channelDAO.listByParentId(parentId);
    }

    @Override
    public List<Channel> listByCompanyId(Integer companyId) {
        return channelDAO.listByCompanyId(companyId);
    }

    @Override
    public List<VtDTO> listVtByChannelAnotherName(String anotherName) throws RuntimeException {
        if (StringUtil.isBlank(anotherName)) {
            log.error("anotherName null error, anotherName:{}", anotherName);
            throw new RuntimeException("anotherName null error");
        }
        List<Channel> channels = channelDAO.listVtByChannelAnotherName(anotherName);

        if (CollectionUtil.isNullOrEmpty(channels)) {
            return Collections.emptyList();
        }

        List<VtDTO> vtDTOList = channels.stream().map(channel -> new VtDTO(channel.getChannelId(), channel.getAnotherName(), channel.getStatus())).distinct().collect(Collectors.toList());
        return vtDTOList;
    }

    @Override
    public List<Channel> listByPlat(Integer plat) {
        return channelDAO.listByPlat(plat);
    }

    @Override
    @ZmnDPermit(types = {DPermitTypeEnum.CHANNEL_C1, DPermitTypeEnum.CHANNEL_C2})
    public List<Channel> listByQuery(ChannelQuery query) {
        return channelDAO.listByQuery(query);
    }

    @Override
    @ZmnDPermit(types = {DPermitTypeEnum.CHANNEL_C1, DPermitTypeEnum.CHANNEL_C2})
    public List<ChannelSimpleVO> listByCombinationQuery(ChannelCombinationQuery query) {
        return channelDAO.listByCombinationQuery(query);
    }

    @Override
    @ZmnDPermit(types = {DPermitTypeEnum.CHANNEL_C1, DPermitTypeEnum.CHANNEL_C2})
    public List<VtDTO> listVtByAppliqueAndRank(Integer applique, Integer rank) {
        return channelDAO.listVtByAppliqueAndRank(applique, rank);
    }

    @Override
    @ZmnDPermit(types = {DPermitTypeEnum.CHANNEL_C1, DPermitTypeEnum.CHANNEL_C2})
    public List<ChannelVO> listChannelVoByQuery(ChannelQuery query) {
        return channelDAO.listChannelVoByQuery(query);
    }

    @Override
    public List<Channel> listAll() {
        return channelDAO.listByQuery(null);
    }

    @Override
    public List<Channel> listByChannelType(Integer channelType) {
        return channelDAO.listByChannelType(channelType);
    }

    @Override
    public List<Channel> listByPlatAndChannelType(Integer plat, Integer channelType) {
        return channelDAO.listByPlatAndChannelType(plat, channelType);
    }

    @Override
    @ZmnDPermit(types = {DPermitTypeEnum.CHANNEL_PLAT, DPermitTypeEnum.CHANNEL_C1, DPermitTypeEnum.CHANNEL_C2})
    public List<Channel> listPageByQuery(ChannelQuery query, Integer staffId) {
        if (!NumberUtil.isNullOrZero(staffId)) {
            query.setOperatorId(staffId);
        }
        Integer count = countByQuery(query);
        query.setTotalCount(count);
        return count == 0 ? null : channelDAO.listPageByQuery(query);
    }


    /**
     * 品牌站变更：渠道试点只能配置二级渠道
     *
     * @return List<Channel>
     * @author yangshuangping
     * @since 2021-6-25 16:05:10
     */
    @Cacheable(key = "'channel:list:enable:level:two'", cacheNames = "redis5m")
    @Override
    public List<Channel> listEnableRankTwoChannel() {

        ChannelQuery channelQuery = new ChannelQuery();
        channelQuery.setStatus(GlobalDict.STATUS_ENABLE);
        channelQuery.setRank(ChannelDict.RANK_TWO);

        return channelDAO.listSimpleChannel(channelQuery);
    }

    @Override
    public List<Channel> listByDimissionChannel(){
        return channelDAO.listByDimissionChannel();
    }

    @Override
    public List<ChannelCountVo> listCountByStatusAndChannelIdsGroupByParentId(List<Integer> channelIds, Integer status) {
        return channelDAO.listCountByStatusAndChannelIdsGroupByParentId(channelIds, status);
    }

    @Override
    @ZmnDPermit(types = {DPermitTypeEnum.CHANNEL_PLAT, DPermitTypeEnum.CHANNEL_C1, DPermitTypeEnum.CHANNEL_C2})
    public Integer countByQuery(ChannelQuery query) {
        return channelDAO.countByQuery(query);
    }

    @Override
    public int updateStatusByIds(List<Integer> channelIds, Integer status, String updater) {
        return channelDAO.updateStatusByIds(channelIds, status, updater);
    }

    @Override
    public int updateByKeySelective(Channel record) {

        record.setUpdateTime(DateUtil.getNow());
        // redis key 删除
        String key = RedisKeyConstant.getKeyChannelDro(record.getChannelId());
        String parentKey = RedisKeyConstant.getKeyParentChannelDro(record.getParentId());
        if (record.getParentId() == null) {
            redisTemplate.delete(key);
        } else {
            List<String> keyList = Arrays.asList(key, parentKey);
            redisTemplate.delete(keyList);
        }
        return channelDAO.updateByKeySelective(record);
    }

    @Override
    public int updateStatusByKey(Channel channel) {
        return channelDAO.updateStatusByKey(channel);
    }

    @Override
    public int updateBaseInfoByKey(Channel record) {
        record.setUpdateTime(DateUtil.getNow());
        return channelDAO.updateBaseInfoByKey(record);
    }

    @Override
    public int updateSortByKey(Integer channelId, Integer sort, String mcStaffName) {
        Channel channel = new Channel();
        channel.setChannelId(channelId);
        channel.setSort(sort);
        channel.setUpdater(mcStaffName);
        channel.setUpdateTime(DateUtil.getNow());
        return channelDAO.updateByKeySelective(channel);
    }

    @Override
    public int insert(Channel record) {
        record.setCreateTime(DateUtil.getNow());
        record.setUpdateTime(DateUtil.getNow());
        return channelDAO.insert(record);
    }

    @Override
    public int deleteByKey(Integer channelId) {
        return channelDAO.deleteByKey(channelId);
    }

}